# -*- coding: latin-1 -*-
#=========================================================================================
from Code.Constantes import *

import os

from PyQt4 import QtGui

import Code.VarGen as VarGen
import Code.Util as Util
import Code.Partida as Partida
import Code.TrListas as TrListas

import Code.QT.Iconos as Iconos
import Code.QT.Controles as Controles
import Code.QT.Colocacion as Colocacion
import Code.QT.QTVarios as QTVarios
import Code.QT.QTUtil2 as QTUtil2
import Code.QT.FormLayout as FormLayout
import Code.QT.Grid as Grid
import Code.QT.Columnas as Columnas
import Code.QT.PantallaPGN as PantallaPGN

#=========================================================================================
class WGames( QtGui.QWidget ) :
    def __init__( self, winBookGuide, dbGames ) :
        QtGui.QWidget.__init__( self )

        self.winBookGuide = winBookGuide
        self.dbGames = dbGames# <--setdbGames

        self.wsummary = None #<-- setSummary
        self.infoMove = None #<-- setInfoMove
        self.summaryActivo = None # movimiento activo en summary
        self.numJugada = 0 # Se usa para indicarla al mostrar el pgn en infoMove

        self.liFiltro = []
        self.siFiltro = False

        # Grid
        oColumnas = Columnas.ListaColumnas()
        oColumnas.nueva( "numero", _( "N." ), 70, siCentrado= True)
        liBasic = ("EVENT","SITE","DATE","WHITE","BLACK","RESULT","ECO","WHITEELO", "BLACKELO", "PLIES" )
        for clave in liBasic :
            rotulo = TrListas.pgnLabel(clave)
            siCentrado = clave != "EVENT"
            oColumnas.nueva( clave, rotulo, 70, siCentrado=siCentrado)

        self.grid = Grid.Grid( self, oColumnas, siSelecFilas = True, siSeleccionMultiple=True, id="wgames" )

        # Status bar
        self.status = QtGui.QStatusBar(self)
        self.btLeerMas = Controles.PB( self, _("Read more games"), rutina = self.leerMas, plano=False )
        self.btLeerMas.setFixedHeight(18)
        self.status.addPermanentWidget( self.btLeerMas )
        self.status.setFixedHeight(22)

        # ToolBar
        liAccionesWork = (
                            ( _( "Close" ), Iconos.MainMenu(), "tw_terminar" ), None,
                            ( _( "Edit" ), Iconos.Modificar(), "tw_editar" ),None,
                            ( _( "First" ), Iconos.Inicio(), "tw_gotop" ),None,
                            ( _( "Last" ), Iconos.Final(), "tw_gobottom" ), None,
                            ( _( "Filter" ), Iconos.Filtrar(), "tw_filtrar" ), None,
                            ( _( "Remove" ), Iconos.Borrar(), "tw_borrar" ),None,
                            ( _( "Show" ), Iconos.PGN(), "tw_mostrar" ), None,
                        )
        tbWork = Controles.TB( self, liAccionesWork, tamIcon = 24 )

        liAccionesGen = (
                            ( _( "Change" ), Iconos.Modificar(), "tg_cambiar" ),None,
                            ( _( "New" ), Iconos.TutorialesCrear(), "tg_crear" ),None,
                            ( _( "Import" ), Iconos.MasDoc(), "tg_importar" ),None,
                            ( _( "Export" ), Iconos.Grabar(), "tg_exportar" ),None,
                            ( _( "Reindex" ), Iconos.Reindexar(), "tg_reindexar" ),None,
                            ( _( "Remove" ), Iconos.Borrar(), "tg_borrar" ),
                            ( _( "Rename" ), Iconos.Rename(), "tg_rename" ),
                        )
        self.tbGen = Controles.TB( self, liAccionesGen, tamIcon = 16, siTexto=True )

        self.lbName = Controles.LB( "" ).ponWrap().alinCentrado().ponColorFondoN( "white", "grey" ).ponTipoLetra(puntos=12)
        lyNT = Colocacion.H().control(self.lbName).control(self.tbGen)

        lyTB = Colocacion.H().control(tbWork)#.relleno(1).control(self.tbGen)

        layout = Colocacion.V().otro(lyNT).otro(lyTB).control(self.grid).control(self.status).margen(1)

        self.setLayout(layout)

        self.setNameToolBar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def setdbGames( self, dbGames ) :
        self.dbGames = dbGames
    #--------------------------------------------------------------------------------------------------------------------------------
    def setSummary( self, wsummary ) :
        self.wsummary = wsummary

    #--------------------------------------------------------------------------------------------------------------------------------
    def setInfoMove( self, infoMove ) :
        self.infoMove = infoMove

    #--------------------------------------------------------------------------------------------------------------------------------
    def setNameToolBar( self ) :
        nomFichero = os.path.basename(self.dbGames.nomFichero)[:-4]
        self.lbName.ponTexto(nomFichero)
        liOthers = self.dbGames.listOthers()
        wd = len(liOthers) > 0
        for key in ( "tg_cambiar", "tg_mezclar", "tg_borrar", "tg_append" ) :
            self.tbGen.setActionVisible( key, wd )

    #--------------------------------------------------------------------------------------------------------------------------------
    def leerMas( self ) :
        pb = QTUtil2.BarraProgreso1( self, _X(_("Reading %1"), "..." ) )
        pb.mostrar()
        total = self.summaryActivo["games"]
        pb.ponTotal( total )
        registros = self.dbGames.reccount()
        pb.pon( registros )
        self.updateStatus()

        while not pb.siCancelado() :
            siPtes = self.dbGames.leerMasRegistros( )
            registros = self.dbGames.reccount()
            pb.pon( registros )
            self.updateStatus()
            if not siPtes :
                break

        pb.cerrar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def updateStatus( self ) :
        if not self.summaryActivo :
            siPte = False
            txt = ""
        else :
            leidos = self.dbGames.reccount()
            siPte = self.dbGames.siFaltanRegistrosPorLeer()
            mv = self.summaryActivo["move"]
            txt = ""
            if mv :
                txt += mv + " | "
            if self.siFiltro :
                regs = "?" if siPte else str(leidos)
                tit = "%s(%s)"%(_( "Games" ),_("Filter")[0])
            else :
                regs = str(self.summaryActivo["games"] if siPte else leidos)
                tit = _( "Games" )

            txt += "%s : %s"%(tit, regs)

            if siPte :
                txt += " | %s : %d"%(_("Read"),leidos)
        self.status.showMessage( txt, 0)
        self.btLeerMas.setVisible(siPte)

    #--------------------------------------------------------------------------------------------------------------------------------
    def gridNumDatos( self, grid ) :
        return self.dbGames.reccount()

    #--------------------------------------------------------------------------------------------------------------------------------
    def gridDato( self, grid, nfila, ocol ) :
        clave = ocol.clave
        if clave == "numero" :
            return str(nfila+1)
        return self.dbGames.field( nfila, clave )

    #--------------------------------------------------------------------------------------------------------------------------------
    def gridDobleClick( self, grid, fil, col ) :
        self.tw_editar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        getattr( self, self.sender().clave )()

    #--------------------------------------------------------------------------------------------------------------------------------
    def actualiza( self, siObligatorio=False ) :
        summaryActivo = self.wsummary.movActivo()
        if siObligatorio or self.summaryActivo != summaryActivo or self.liFiltro :
            self.siFiltro = False
            self.summaryActivo = summaryActivo

            pv = self.summaryActivo["pv"] if self.summaryActivo else ""
            self.dbGames.filterPV( pv )
            self.numJugada = pv.count(" ")
            self.grid.refresh()
            self.grid.gotop()
            self.updateStatus( )
        recno = self.grid.recno()
        if recno >= 0 :
            self.gridCambiadoRegistro( None, recno, None )
        if self.gridNumDatos(None) == 0 :
            self.btLeerMas.setVisible(False)

    #--------------------------------------------------------------------------------------------------------------------------------
    def gridCambiadoRegistro( self, grid, fila, oCol ) :
        pv = self.dbGames.damePV(fila)
        p = Partida.Partida()
        p.leerPV(pv)
        p.compruebaFinal()
        self.infoMove.modoPartida(p,self.numJugada)
        self.setFocus()
        self.grid.setFocus()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_gobottom( self ) :
        self.grid.gobottom()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_gotop( self ) :
        self.grid.gotop()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_terminar( self ) :
        self.winBookGuide.terminar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_editar( self ) :
        li = self.grid.recnosSeleccionados()
        if li:
            recno = li[0]
            # Se genera un PGN
            pgn = self.dbGames.leePGNrecno(recno)

            nuevoPGN, pv, dicPGN = VarGen.procesador.gestorUnPGN( self, pgn )
            if nuevoPGN :
                self.dbGames.cambiarUno( recno, nuevoPGN, pv, dicPGN )
                self.grid.refresh()
                self.updateStatus()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_filtrar( self ) :
        w = PantallaPGN.WFiltrar( self, self.grid.oColumnas, self.liFiltro )
        if w.exec_() :
            self.liFiltro = w.liFiltro
            self.siFiltro = True

            where = ""
            for union, par0, campo, condicion, valor, par1 in self.liFiltro :
                valor = valor.upper()
                if condicion == "LIKE" :
                    valor = valor.replace("*", "%")
                    if "%" not in valor :
                        valor = "%" + valor + "%"

                if union :
                    where += " %s "% union
                where += par0
                if condicion in ( "=", "<>" ) and not valor :
                    where += "(( %s %s ) OR (%s %s ''))"%(campo, "IS NULL" if condicion == "=" else "IS NOT NULL", campo, condicion )
                else :
                    where += "UPPER(%s) %s '%s'"%(campo,condicion,valor.upper())
                where += par1

            self.dbGames.filterPV( self.summaryActivo["pv"], where )
            self.grid.refresh()
            self.grid.gotop()
            self.updateStatus()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_borrar( self ) :
        li = self.grid.recnosSeleccionados()
        if li:
            if not QTUtil2.pregunta( self, _( "Want you delete all selected records?" ) ) :
                return

            um = QTUtil2.unMomento(self)

            self.dbGames.borrarLista( li )
            self.summaryActivo["games"] -= len(li)
            self.grid.refresh()
            self.updateStatus()

            um.final()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_reindexar( self ) :
        if not QTUtil2.pregunta( self, _( "Do you want to rebuild stats?" ) ) :
            return

        # Select depth
        liGen = [(None,None)]
        liGen.append( ( None, _("Select the number of moves <br> for each game to be considered") ) )
        liGen.append((None,None))

        li = [ (str(n),n) for n in range( 3, 255 ) ]
        config = FormLayout.Combobox( _( "Depth" ), li )
        liGen.append( ( config, self.dbGames.depthStat() ) )

        resultado = FormLayout.fedit( liGen, title=_("Rebuild"), parent = self, icon = Iconos.Reindexar() )
        if resultado is None :
            return None

        accion, liResp = resultado

        depth = liResp[0]

        self.RECCOUNT = 0

        bpTmp = QTUtil2.BarraProgreso1( self, _("Rebuilding") )
        bpTmp.mostrar()

        def dispatch( recno, reccount ) :
            if reccount != self.RECCOUNT :
                self.RECCOUNT = reccount
                bpTmp.ponTotal( reccount )
            bpTmp.pon(recno)
            return not bpTmp.siCancelado()

        self.dbGames.recrearSTAT( dispatch, depth )
        bpTmp.cerrar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_exportar( self ) :
        li = self.grid.recnosSeleccionados()
        if li:
            menu = QTVarios.LCMenu()
            menu.opcion( False, _("Only selected"), Iconos.PuntoAzul() )
            menu.separador()
            menu.opcion( True, _("All read"), Iconos.PuntoVerde() )
            resp = menu.lanza()
            if resp is None :
                return
            siTodos = resp
            if siTodos :
                li = range(self.dbGames.reccount())

            # Fichero donde a?adir
            configuracion = VarGen.configuracion
            pathPGN = QTUtil2.salvaFichero( self, _( "Export" ), configuracion.dirSalvados, _("File")+" pgn (*.pgn)", False )
            if pathPGN :
                carpeta,nomf = os.path.split( pathPGN )
                if carpeta != configuracion.dirSalvados :
                    configuracion.dirSalvados = carpeta
                    configuracion.graba()

                # Grabamos
                tamF = Util.tamFichero(pathPGN)
                try :
                    fpgn = open( pathPGN, "ab" )
                except :
                    QTUtil2.mensError( self, "%s : %s\n"%( _("Unable to save"),pathPGN.replace("/", "\\") ) )
                    return

                pb = QTUtil2.BarraProgreso1( self, _("Exporting..." ) )
                pb.mostrar()
                total = len(li)
                pb.ponTotal( total )

                siCancelado = False
                if tamF :
                    fpgn.write( "\n" )
                for recno in li :
                    pgn = self.dbGames.field( recno, "PGN" )
                    pb.pon( recno+1 )
                    if pb.siCancelado() :
                        siCancelado = True
                        break
                    fpgn.write( Util.blob2var(pgn) )
                    fpgn.write( "\n" )

                fpgn.close()
                pb.cerrar()
                if not siCancelado :
                    QTUtil2.mensaje( self, _X(_( "Saved on %1" ),pathPGN.replace("/", "\\") ) )

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_importar( self ) :
        configuracion = VarGen.configuracion
        # Elegimos el fichero PGN
        path = QTUtil2.leeFichero( self, configuracion.dirPGN, "pgn" )
        if not path  :
            return None
        carpeta, fichero = os.path.split(path)
        if configuracion.dirPGN != carpeta :
            configuracion.dirPGN = carpeta
            configuracion.graba()

        bpTmp = QTUtil2.BarraProgreso2( self, _("Import") ).mostrar()

        def dispatch( orden, num = 0) :
            if orden == "CLEANING" :
                bpTmp.ponRotulo( 1, "1. "+_X(_("Reading %1"), fichero) )
                bpTmp.ponTotal( 1, -1 )
                if bpTmp.siCancelado() :
                    return False
            elif orden == "WORK" :
                bpTmp.ponTotal( 1, 1 )
                bpTmp.pon( 1, 1 )
                bpTmp.ponTotal(2, num)
                bpTmp.ponRotulo( 2, "2. "+_X(_("Converting %1"),fichero).strip())
            elif orden == "NEXT" :
                bpTmp.pon(2,num)
                if bpTmp.siCancelado() :
                    return False
            elif orden == "END_0" :
                bpTmp.hide()
                QTUtil2.unMomento(self)
            elif orden == "END_1" :
                QTUtil2.mensEspera.final()
            return True

        # Lanzamos la lectura
        processed, matched, duplicated = self.dbGames.leerPGN( path, True, dispatch )

        bpTmp.cerrar()

        txt = "%s : %d\n%s : %d\n%s : %d\n%s : %d"%( _("Read"), processed, _("Correct"), matched, _("Duplicates"), duplicated, _("Imported"), matched-duplicated)

        QTUtil2.mensaje( self, txt, fichero )

        self.actualiza( True )

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_nombre_depth( self, titulo, previous = "", siDepth=True ) :
        # Pide nombre + depth
        nombre = previous
        if siDepth :
            depth = self.dbGames.depthStat()

        while True :

            liGen = [(None,None)]
            liGen.append( ( _( "Name" ) + " :", nombre ) )

            if siDepth :
                liGen.append((None,None))
                liGen.append( ( None, _("Select the number of moves <br> for each game to be considered") ) )

                li = [ (str(n),n) for n in range( 3, 255 ) ]
                config = FormLayout.Combobox( _( "Depth" ), li )
                liGen.append( ( config, depth ) )

            resultado = FormLayout.fedit( liGen, title=titulo, parent = self, anchoMinimo = 460, icon = Iconos.TutorialesCrear() )
            if resultado is None :
                return None

            accion, liResp = resultado

            nombre = Util.validNomFichero(liResp[0])

            if not nombre :
                return None

            if siDepth :
                depth = liResp[1]

            configuracion = VarGen.configuracion

            fich = os.path.join( configuracion.carpeta, nombre + ".lcg" )
            if Util.existeFichero( fich ) :
                QTUtil2.mensError( self, _("This file already exists, choose another name") )
                continue

            if siDepth :
                return nombre, depth
            else :
                return nombre

    #--------------------------------------------------------------------------------------------------------------------------------
    def changeDBgames( self, nombre ) :
        fich = os.path.join(VarGen.configuracion.carpeta,nombre+".lcg")
        configuracion = VarGen.configuracion
        configuracion.ficheroDBgames = fich
        configuracion.graba()
        self.winBookGuide.cambiaDBgames( fich )
        self.setNameToolBar()
        self.actualiza(True)

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_crear( self ) :
        resp = self.tg_nombre_depth( _("New") )

        if resp :
            nombre, depth = resp
            self.changeDBgames( nombre )

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_cambiar( self ) :
        liOthers = self.dbGames.listOthers()
        menu = QTVarios.LCMenu()
        for uno in liOthers :
            menu.opcion( uno, uno, Iconos.PuntoAzul() )
            menu.separador()
        resp = menu.lanza()
        if resp :
            self.changeDBgames( resp )

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_rename( self ) :
        name = os.path.basename(self.dbGames.nomFichero)[:-5]
        name = self.tg_nombre_depth( "Rename", previous = name, siDepth=False )
        if not name :
            return

        self.dbGames.close()
        antiguo = self.dbGames.nomFichero
        nuevo = os.path.join( VarGen.configuracion.carpeta, name +".lcg" )
        os.rename( antiguo, nuevo )
        os.rename( antiguo +"-stat", nuevo +"-stat" )

        self.changeDBgames( name )

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_borrar( self ) :
        liOthers = self.dbGames.listOthers()
        menu = QTVarios.LCMenu()
        for uno in liOthers :
            menu.opcion( uno, uno, Iconos.PuntoAzul() )
            menu.separador()
        resp = menu.lanza()
        if resp :
            if QTUtil2.pregunta( self, _X(_( "Delete %1 ?"), resp ) ) :
                fich = os.path.join(VarGen.configuracion.carpeta,resp+".lcg")
                Util.borraFichero( fich )
                Util.borraFichero( fich + "-stat" )
                self.setNameToolBar()
